// Magic Software, Inc.
// http://www.magic-software.com
// Copyright (c) 2000, All Rights Reserved
//
// Source code from Magic Software is supplied under the terms of a license
// agreement and may not be copied or disclosed except in accordance with the
// terms of that agreement.  The various license agreements may be found at
// the Magic Software web site.  This file is subject to the license
//
// RESTRICTED USE SOURCE CODE
// http://www.magic-software.com/License/restricted.pdf

#include "MgcAmbientLight.h"
#include "MgcDirectionalLight.h"
#include "MgcPointLight.h"
#include "MgcSpotLight.h"
#include "MgcOglRenderer.h"

//----------------------------------------------------------------------------
void MgcOglRenderer::SetLightState (MgcLightState* pkState)
{
    unsigned int uiQuantity = pkState->GetQuantity();

    if ( uiQuantity > 0 )
    {
        glEnable(GL_LIGHTING);

        GLfloat afAmbient[4] = { 0.0, 0.0, 0.0, 1.0 };
        GLfloat afColor[4];
        afColor[3] = 1.0;

        unsigned int uiI;
        for (uiI = 0; uiI < uiQuantity; uiI++)
        {
            MgcLight* pkLight = pkState->Get(uiI);
            GLint iIndex = GL_LIGHT0 + uiI;
            glEnable(iIndex);

            afColor[0] = pkLight->Ambient().r;
            afColor[1] = pkLight->Ambient().g;
            afColor[2] = pkLight->Ambient().b;
            glLightfv(iIndex,GL_AMBIENT,afColor);

            afColor[0] = pkLight->Diffuse().r;
            afColor[1] = pkLight->Diffuse().g;
            afColor[2] = pkLight->Diffuse().b;
            glLightfv(iIndex,GL_DIFFUSE,afColor);

            afColor[0] = pkLight->Specular().r;
            afColor[1] = pkLight->Specular().g;
            afColor[2] = pkLight->Specular().b;
            glLightfv(iIndex,GL_SPECULAR,afColor);

            if ( pkLight->Attenuate() )
            {
                glLightf(iIndex,GL_CONSTANT_ATTENUATION,
                    pkLight->Constant());
                glLightf(iIndex,GL_LINEAR_ATTENUATION,
                    pkLight->Linear());
                glLightf(iIndex,GL_QUADRATIC_ATTENUATION,
                    pkLight->Quadratic());
            }
            else
            {
                glLightf(iIndex,GL_CONSTANT_ATTENUATION,1.0);
                glLightf(iIndex,GL_LINEAR_ATTENUATION,0.0);
                glLightf(iIndex,GL_QUADRATIC_ATTENUATION,0.0);
            }

            if ( pkLight->GetType() == MgcLight::LT_AMBIENT )
            {
                afAmbient[0] += pkLight->Ambient().r;
                afAmbient[1] += pkLight->Ambient().g;
                afAmbient[2] += pkLight->Ambient().b;
            }

            GLfloat afPosParam[4];
            switch ( pkLight->GetType() )
            {
            case MgcLight::LT_DIRECTIONAL:
            {
                MgcDirectionalLight* pkDL = (MgcDirectionalLight*) pkLight;
                afPosParam[0] = -pkDL->Direction().x;
                afPosParam[1] = -pkDL->Direction().y;
                afPosParam[2] = -pkDL->Direction().z;
                afPosParam[3] = 0.0;
                glLightfv(iIndex,GL_POSITION,afPosParam);
                break;
            }
            case MgcLight::LT_POINT:
            case MgcLight::LT_SPOT:
            {
                MgcPointLight* pkPL = (MgcPointLight*) pkLight;
                afPosParam[0] = pkPL->Location().x;
                afPosParam[1] = pkPL->Location().y;
                afPosParam[2] = pkPL->Location().z;
                afPosParam[3] = 1.0;
                break;
            }
            }

            if ( pkLight->GetType() == MgcLight::LT_SPOT )
            {
                MgcSpotLight* pkSpot = (MgcSpotLight*) pkLight;
                glLightf(iIndex,GL_SPOT_CUTOFF,
                    180.0*pkSpot->GetAngle()/MgcMath::PI);
                glLightfv(iIndex,GL_SPOT_DIRECTION,
                    (const GLfloat*)pkSpot->Direction());
                glLightf(iIndex,GL_SPOT_EXPONENT,
                    pkSpot->Exponent());
            }
            else
            {
                GLfloat afDefaultDirection[3] = { 0.0, 0.0, -1.0 };
                glLightf(iIndex,GL_SPOT_CUTOFF,180.0);
                glLightfv(iIndex,GL_SPOT_DIRECTION,afDefaultDirection);
                glLightf(iIndex,GL_SPOT_EXPONENT,0.0);
            }
        }

        glLightModelfv(GL_LIGHT_MODEL_AMBIENT,afAmbient);

        for (uiI = uiQuantity; uiI < MgcLightState::MAX_LIGHTS; uiI++)
            glDisable(GL_LIGHT0 + uiI);
    }
    else
    {
        glDisable(GL_LIGHTING);
    }
}
//----------------------------------------------------------------------------
